import * as server_ui from "@minecraft/server-ui";
import * as server from "@minecraft/server";
import * as data_format from "../data/format";
import * as data_story from "../data/story";
import * as power_property from "../system/power_property";
import * as derived_tools from "../system/derived_tools";
import * as native_tools from "../system/native_tools";
import * as achieve_plan from "../system/achieve_plan";
import * as math_tools from "../system/math_tools";
function IncreaseDamage(player, container, single = true) {
    for (let index = 0; index < container.size; index++) {
        const item = container.getItem(index);
        if (!item || !item.hasTag('data_tag:energy_crystal.series'))
            continue;
        const typeID = item.typeId.split(/:/)[1];
        if (typeID == 'eternal_energy')
            continue;
        if (single)
            only(item);
        else
            all(item);
        break;
    }
    ;
    function only(item) {
        const sample = new server.ItemStack(item.typeId);
        const stages = power_property.GetProperty(player);
        const raise_basic_attack = stages.raise_basic_attack + (stages.basic_attack) * 2;
        power_property.AlterProperty(player, { raise_basic_attack });
        native_tools.DeleteItemStack(container, sample);
    }
    ;
    function all(item) {
        const sample = new server.ItemStack(item.typeId, item.amount);
        const stages = power_property.GetProperty(player);
        const raise_basic_attack = ((stages.raise_basic_attack + (stages.basic_attack) * 2) * item.amount) + 3;
        power_property.AlterProperty(player, { raise_basic_attack });
        native_tools.DeleteItemStack(container, sample);
    }
}
;
export function MagicCrystalWrenchTrigger() {
    return {
        onUse(source) {
            const player = source.source;
            const item = source.itemStack;
            const container = player.getComponent('inventory')?.container;
            if (!container || !player || !item)
                return;
            if (!achieve_plan.ControlEventTrigger.EntityToken(item.typeId, player, 20))
                return;
            const title = {
                text: "<§9§o§l 魔晶扳手 §r>§2操作界面"
            };
            const option = [
                { text: '§l<§n§o 元素附魔 §u-§c 赤焰 §5>§r' },
                { text: '§l<§n§o 元素附魔 §u-§b 海蓝 §5>§r' },
                { text: '§l<§n§o 元素附魔 §u-§a 森绿 §5>§r' },
                { text: '§l<§n§o 元素附魔 §u-§d 紫雷 §5>§r' },
                { text: '§l<§n§o 元素附魔 §u-§p 橙岩 §5>§r' },
                { text: '§l<§n§o 元素附魔 §u-§i 白星 §5>§r' },
                { text: '§l<§n§o 元素附魔 §u-§j 黑渊 §5>§r' }
            ];
            const display = new server_ui.ActionFormData()
                .title(title)
                .button(option[0], "textures/物品贴图/能量水晶/赤焰_魔晶石")
                .button(option[1], "textures/物品贴图/能量水晶/海蓝_魔晶石")
                .button(option[2], "textures/物品贴图/能量水晶/森绿_魔晶石")
                .button(option[3], "textures/物品贴图/能量水晶/紫雷_魔晶石")
                .button(option[4], "textures/物品贴图/能量水晶/橙岩_魔晶石");
            const enchanting = (nameTag, selfRune) => {
                item.setDynamicProperty('rune_hurt:self_rune', selfRune);
                item.nameTag = nameTag;
                item.setLore(['攻击命中后, 将获得' + nameTag]);
                container.setItem(player.selectedSlotIndex, item);
                player.playSound('block.enchanting_table.use');
            };
            player.playSound('tile.piston.out');
            display.show(player).then(option => {
                if (option.canceled)
                    return;
                switch (option.selection) {
                    case 0:
                        enchanting('§l<§n§o 元素附魔 §u-§c 赤焰 §5>§r', data_format.RUNE_ENUM.red);
                        break;
                    case 1:
                        enchanting('§l<§n§o 元素附魔 §u-§b 海蓝 §5>§r', data_format.RUNE_ENUM.blue);
                        break;
                    case 2:
                        enchanting('§l<§n§o 元素附魔 §u-§a 森绿 §5>§r', data_format.RUNE_ENUM.green);
                        break;
                    case 3:
                        enchanting('§l<§n§o 元素附魔 §u-§d 紫雷 §5>§r', data_format.RUNE_ENUM.purple);
                        break;
                    case 4:
                        enchanting('§l<§n§o 元素附魔 §u-§p 橙岩 §5>§r', data_format.RUNE_ENUM.orange);
                        break;
                    case 5:
                        enchanting('§l<§n§o 元素附魔 §u-§i 白星 §5>§r', data_format.RUNE_ENUM.white);
                        break;
                    case 6:
                        enchanting('§l<§n§o 元素附魔 §u-§j 黑渊 §5>§r', data_format.RUNE_ENUM.black);
                        break;
                }
            });
            item.getComponent('minecraft:cooldown')?.startCooldown(player);
        },
        onHitEntity(source) {
            const player = source.attackingEntity;
            const container = player.getComponent('inventory')?.container;
            const item = source.itemStack;
            const target = source.hitEntity;
            if (!(player instanceof server.Player) || !item || !target || !container)
                return;
            if (!achieve_plan.ControlEventTrigger.EntityToken(item.typeId, player, 10))
                return;
            const stages = power_property.GetProperty(player);
            const particle = stages.self_rune != 'rune_void' ? 'constant:impact_' + stages.self_rune : 'minecraft:sonic_explosion';
            const options = {
                excludeTypes: ["minecraft:item", "minecraft:xp_orb"],
                excludeFamilies: ['starry'],
                location: target?.location,
                maxDistance: 4,
                closest: 8
            };
            const getQueue = player.dimension.getEntities(options).filter(entity => entity.id !== player.id);
            const erupt = derived_tools.IsErupt(player);
            const self_rune = item.getDynamicProperty('rune_hurt:self_rune') ?? 'rune_void';
            power_property.SetProperty(player, { self_rune: self_rune });
            IncreaseDamage(player, container);
            getQueue.forEach(entity => achieve_plan.RunePowerAttack.BriefCreate(player, entity, erupt));
            native_tools.TrySpawnParticle(player.dimension, "minecraft:huge_explosion_emitter", target?.location ?? player.location);
            native_tools.TrySpawnParticle(player.dimension, particle, target?.location ?? player.location);
            item.getComponent('minecraft:cooldown')?.startCooldown(player);
            native_tools.SetDurability(player, item, container, player.selectedSlotIndex, 1);
        }
    };
}
;
export function MagicCrystalMarblesTrigger() {
    return {
        onUse(source) {
            const player = source.source;
            const item = source.itemStack;
            const container = player.getComponent('inventory')?.container;
            if (!container || !player || !item)
                return;
            if (!achieve_plan.ControlEventTrigger.EntityToken(item.typeId, player, 20))
                return;
            player.playAnimation('animation.item.common.resist', { blendOutTime: 0.5 });
            player.playSound('item.trident.riptide_1');
            const target = player.getEntitiesFromViewDirection({ maxDistance: 48 })[0]?.entity;
            if (!target || !target.isValid())
                return;
            const options = {
                excludeTypes: ["minecraft:item", "minecraft:xp_orb"],
                excludeFamilies: ['starry'],
                location: target.location,
                maxDistance: 8,
                closest: 8
            };
            const queue = player.dimension.getEntities(options).filter(entity => entity.id !== player.id);
            if (queue.length == 0 || !target)
                return;
            IncreaseDamage(player, container, false);
            const data = power_property.GetProperty(player);
            const blastParticle = 'constant:fireworks_fireball_' + data.self_rune;
            const erupt = derived_tools.IsErupt(player);
            const molang = new server.MolangVariableMap();
            const distance = math_tools.Vector.distance(player.location, target.location);
            const sample = new server.ItemStack(item.typeId);
            native_tools.DeleteItemStack(container, sample);
            molang.setColorRGB('variable.color', data_story.getRuneColor(data.self_rune));
            molang.setVector3('variable.direction', player.getViewDirection());
            molang.setFloat('variable.range', distance);
            molang.setFloat('variable.type', 0);
            player.spawnParticle('scripts:path_spurt', player.getHeadLocation(), molang);
            server.system.runTimeout(() => {
                if (!target || !target.isValid())
                    return;
                queue.forEach(entity => achieve_plan.RunePowerAttack.BriefCreate(player, entity, erupt, data));
                if (queue.length > 1)
                    native_tools.TrySpawnParticle(player.dimension, blastParticle, target.location);
            }, distance);
        }
    };
}
;
export function MagicCrystalBowTrigger() {
    return {
        onUse(source) {
            const player = source.source;
            const item = source.itemStack;
            const container = player.getComponent('inventory')?.container;
            if (!container || !player || !item)
                return;
            if (!achieve_plan.ControlEventTrigger.EntityToken(item.typeId, player, 10))
                return;
            if (player.isSneaking)
                BowSneaking(player);
            else {
                const data = power_property.GetProperty(player);
                power_property.SetProperty(player, { raise_basic_attack: 0 });
                IncreaseDamage(player, container);
                player.spawnParticle('constant:excite_' + data.self_rune, player.getHeadLocation());
            }
            item.getComponent('minecraft:cooldown')?.startCooldown(player);
            native_tools.SetDurability(player, item, container, player.selectedSlotIndex, 1);
        }
    };
}
;
function BowTick(args) {
    const getBlock = args.dimension.getBlock(args.location);
    if (!getBlock || !getBlock.isValid())
        return false;
    if (getBlock && getBlock.isAir)
        return true;
    return false;
}
;
function BowStop(args) {
    const block = args.dimension.getBlock(args.location);
    if (!block || !block.isValid())
        return;
    const blocks = [];
    for (let axleX = -1; axleX < 2; axleX++)
        for (let axleY = -1; axleY < 2; axleY++)
            for (let axleZ = -1; axleZ < 2; axleZ++) {
                const sample = block.offset({ x: axleX, y: axleY, z: axleZ });
                if (sample)
                    blocks.push(sample);
            }
    ;
    for (let index = 0; index < blocks.length; index++) {
        if (!blocks[index].isAir || blocks[index].below()?.isAir || blocks[index].below()?.isLiquid)
            continue;
        blocks[index].setPermutation(server.BlockPermutation.resolve('minecraft:soul_torch'));
        break;
    }
    ;
}
;
function BowSneaking(object) {
    achieve_plan.PathExecute.Create('魔晶弹弓-照明射线', 1, {
        particles: ['constant:track_color_yellow'],
        dimension: object.dimension,
        location_group: [],
        on_move: BowTick,
        on_done: BowStop,
        cooldown: 1,
        speed: 1,
        shoot: {
            start_place: object.getHeadLocation(),
            toward: object.getViewDirection(),
            max_distance: 128
        }
    });
}
;
export function BowHitAfter(object, target) {
    const data = power_property.GetProperty(object);
    const molang = new server.MolangVariableMap();
    if (!target)
        return;
    molang.setColorRGB('variable.color', data_story.getRuneColor(data.self_rune));
    molang.setVector3('variable.direction', math_tools.Vector.CONSTANT_DOWN);
    molang.setFloat('variable.range', 5);
    molang.setFloat('variable.type', 0);
    object.spawnParticle('scripts:path_spurt', math_tools.Vector.add(target.location, { x: 0, y: 5, z: 0 }), molang);
    const erupt = derived_tools.IsErupt(object);
    achieve_plan.RunePowerAttack.Create(object.id, 10, { target: target, self: object, erupt });
}
;
export function MagicCrystalScrewdriverTrigger() {
    return {
        onUse(source) {
            const player = source.source;
            const item = source.itemStack;
            const container = player.getComponent('inventory')?.container;
            if (!container || !player || !item)
                return;
            if (!achieve_plan.ControlEventTrigger.EntityToken(item.typeId, player, 20))
                return;
            const title = {
                text: "<§9§o§l 区块连锁 §r>§2操作界面"
            };
            const label = { text: '区块连锁 -> 用法' };
            const slider = [
                { text: '<§9§o§l 区块连锁 §r>极限深度§r' },
                { text: '<§9§o§l 区块连锁 §r>极限高度§r' },
                { text: '<§9§o§l 区块连锁 §r>极限范围§r' }
            ];
            const option = [
                { text: '§l§1[§9 潜行触发 §1]§r' },
                { text: '§l§c[§c 关闭功能 §c]§r' },
                { text: '§l§1[§4 始终触发 §1]§r' }
            ];
            new server_ui.ModalFormData()
                .title(title)
                .slider(slider[0], -8, -1, 1, -6)
                .slider(slider[1], 1, 8, 1, 6)
                .slider(slider[2], 4, 8, 1, 6)
                .dropdown(label, option, 1)
                .show(player).then(popup => {
                if (popup.canceled)
                    return;
                const mode = ['潜行', undefined, '始终'];
                const formValues = popup.formValues;
                player.sendMessage(option[formValues[3]]);
                player.setDynamicProperty('block_chain:type', mode[formValues[3]]);
                player.setDynamicProperty('block_chain:depth', formValues[0]);
                player.setDynamicProperty('block_chain:height', formValues[1]);
                player.setDynamicProperty('block_chain:range', formValues[2]);
            });
            player.playSound("break.amethyst_block");
            item.getComponent('minecraft:cooldown')?.startCooldown(player);
            native_tools.SetDurability(player, item, container, player.selectedSlotIndex, 1);
        }
    };
}
;
export function MagicCrystalHoeTrigger() {
    return {
        onUse(source) {
            const player = source.source;
            const item = source.itemStack;
            const container = player.getComponent('inventory')?.container;
            if (!container || !player || !item)
                return;
            if (!achieve_plan.ControlEventTrigger.EntityToken(item.typeId, player, 60))
                return;
            player.playSound("random.bow");
            const getBlock = player.getBlockFromViewDirection({ maxDistance: 128 })?.block;
            if (!getBlock || !getBlock.isValid())
                return;
            const getGroup = [];
            for (let axleX = -2; axleX < 2; axleX++)
                for (let axleY = -2; axleY < 2; axleY++)
                    for (let axleZ = -2; axleZ < 2; axleZ++) {
                        const current = getBlock.offset({ x: axleX, y: axleY, z: axleZ });
                        const above = getBlock.offset({ x: axleX, y: axleY + 1, z: axleZ });
                        if (current?.isAir && above?.isAir)
                            getGroup.push(current);
                    }
            ;
            const camera = player.camera;
            const options = {
                amplifier: 0,
                showParticles: false
            };
            if (getGroup.length < 1)
                return;
            const block = getGroup[0];
            server.system.runTimeout(() => camera.clear(), 40);
            camera.setCamera('minecraft:free', { location: block, rotation: player.getRotation(), easeOptions: { easeTime: 2 } });
            native_tools.TrySpawnParticle(block.dimension, 'constant:magic_hoe', block.location);
            server.system.runTimeout(() => camera.fade({ fadeColor: { red: 0, green: 0, blue: 0 }, fadeTime: { fadeInTime: 0.2, fadeOutTime: 0.3, holdTime: 0.5 } }), 30);
            server.system.runTimeout(() => {
                player.tryTeleport(block);
                player.addEffect("slow_falling", 200, options);
                player.addEffect("levitation", 80, options);
            }, 40);
            item.getComponent('minecraft:cooldown')?.startCooldown(player);
            native_tools.SetDurability(player, item, container, player.selectedSlotIndex, 1);
        }
    };
}
;
export function MagicCrystalShield(player, item, slot) {
    const equippable = player.getComponent('minecraft:equippable');
    player.playAnimation('animation.item.shield.resist', { blendOutTime: 0.5 });
    player.playSound('item.shield.block');
    equippable?.setEquipment(slot, native_tools.AlterDurability(item, 1));
    if (!achieve_plan.ControlEventTrigger.EntityToken('魔晶盾牌:伤害反射', player, 60))
        return;
    if (!player.isSneaking)
        return;
    item.getComponent('minecraft:cooldown')?.startCooldown(player);
    ShieldReflexDamage(player, item);
}
;
function ShieldReflexDamage(player, item) {
    const options = {
        excludeTypes: ["minecraft:item", "minecraft:xp_orb"],
        excludeFamilies: ['starry'],
        location: player.location,
        maxDistance: 4
    };
    const getData = power_property.GetProperty(player);
    player.dimension.getEntities(options).filter(entity => entity.id !== player.id).forEach(entity => achieve_plan.RunePowerAttack.Create('SprayPack', 1, { target: entity, self: player, erupt: true, hurt_data: getData }));
    if (getData.self_rune !== data_format.RUNE_ENUM.void)
        native_tools.TrySpawnParticle(player.dimension, `constant:impact_${getData.self_rune}`, player.location);
    if (getData.self_rune === data_format.RUNE_ENUM.void)
        native_tools.TrySpawnParticle(player.dimension, 'minecraft:sonic_explosion', player.location);
    item.getComponent('minecraft:cooldown')?.startCooldown(player);
}
;
export function MagicCrystalHammer(player, item, container, block) {
    const pointer = block?.above();
    if (!pointer)
        return;
    const material = pointer.dimension.getEntitiesAtBlockLocation(pointer.location);
    for (let index = 0; index < material.length; index++) {
        const item = material[index].getComponent('item')?.itemStack;
        if (!item || item?.amount < 4)
            continue;
        const tags = item?.getTags().filter(tag => tag.startsWith('data_tag:mineral_resources.make'));
        if (tags.length == 0)
            continue;
        const type = tags[0].split('.')[2];
        const stage = item.typeId.split(':')[1].split('.').length;
        const name = stage == 1 ? item.typeId.split(':')[1] : item.typeId.split(':')[1].split('.')[1];
        material[index].remove();
        if (item.amount > 4) {
            item.amount -= 4;
            native_tools.TrySpawnItem(pointer.dimension, item, pointer.center());
        }
        ;
        native_tools.TrySpawnItem(pointer.dimension, new server.ItemStack('item_mineral:' + type + '.' + name), pointer.center());
        player.playSound('random.anvil_use');
        break;
    }
    ;
    item.getComponent('minecraft:cooldown')?.startCooldown(player);
    native_tools.SetDurability(player, item, container, player.selectedSlotIndex, 1);
}
;
export function MagicCrystalKey(player, item, container, block) {
    const whiteList = new Set([
        'minecraft:trial_spawner',
        'minecraft:mob_spawner',
        'minecraft:vault'
    ]);
    const inventory = block?.getComponent('inventory')?.container;
    if (!block)
        return;
    if (!inventory && !whiteList.has(block?.typeId))
        return;
    const chest = block.getItemStack(1, true);
    if (chest)
        chest.setLore([
            `搬运者: ${player.nameTag}`,
            `源坐标: ${math_tools.Vector.toString(block)}`,
            `源维度: ${block.dimension.id}`
        ]);
    if (chest)
        native_tools.TrySpawnItem(block.dimension, chest, block.center());
    if (inventory)
        for (let index = 0; index < inventory.size; index++)
            inventory.setItem(index);
    block.setPermutation(server.BlockPermutation.resolve('minecraft:air'));
    player.playSound('block.barrel.open');
    item.getComponent('minecraft:cooldown')?.startCooldown(player);
    native_tools.SetDurability(player, item, container, player.selectedSlotIndex, 1);
}
;
